package com.cloudpan.common;


import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;

/**
 * 响应信息主体封装类</br>
 * 1、将后端执行结构进行封装返回；</br>
 * 2、返回的属性code为0，则执行成功，返回为1，则执行失败；</br>
 * 3、属性msg为后端返回的信息；</br>
 * 4、泛型data为后端返回前端的数据；</br>
 *
 * @param <T>	构建类型
 * @author gaoxiang
 */
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Slf4j
@ApiModel("接口返回数据")
public class R<T> implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 返回状态码：0成功，1失败
	 */
	@ApiModelProperty(value="返回状态码：0成功，1失败")
	private int code;
	/**
	 * 返回信息
	 */
	@ApiModelProperty(value="返回信息")
	private String msg;

	/**
	 * 返回数据
	 */
	@ApiModelProperty(value="返回数据")
	private T data;

	/**
	 * 返回成功
	 * @param <T>	构建类型
	 * @return	返回封装数据
	 */
	public static <T> R<T> ok() {
		return restResult(null, ResultCodeMsg.SUCCESS.getCode(), ResultCodeMsg.SUCCESS.getMsg());
	}

	/**
	 * 返回成功带数据
	 * @param msg	返回成功消息
	 * @param <T>	构建类型
	 * @return	返回封装数据
	 */
	public static <T> R<T> ok(String msg) {
		return restResult(null,  ResultCodeMsg.SUCCESS.getCode(), msg);
	}

	/**
	 * 返回成功带数据
	 * @param data	返回成功数据
	 * @param <T>	构建类型
	 * @return	返回封装数据
	 */
	public static <T> R<T> ok(T data) {
		return restResult(data, ResultCodeMsg.SUCCESS.getCode(), null);
	}

	/**
	 * 返回成功带数据和消息
	 * @param data	返回数据
	 * @param msg	返回消息
	 * @param <T>	构建类型
	 * @return	返回封装数据
	 */
	public static <T> R<T> ok(T data, String msg) {
		return restResult(data,  ResultCodeMsg.SUCCESS.getCode(), msg);
	}

	/**
	 * 返回失败
	 * @param <T>	构建类型
	 * @return	返回封装数据
	 */
	public static <T> R<T> failed() {
		return restResult(null, ResultCodeMsg.FAIL.getCode(), null);
	}

	/**
	 * 返回失败
	 * @param msg	失败消息
	 * @param <T>	构建类型
	 * @return	返回封装数据
	 */
	public static <T> R<T> failed(String msg) {
		log.error(msg);
		return restResult(null, ResultCodeMsg.FAIL.getCode(), msg);
	}

	/**
	 * 返回失败带数据
	 * @param data	失败数据
	 * @param <T>	构建类型
	 * @return	返回封装数据
	 */
	public static <T> R<T> failed(T data) {
		return restResult(data, ResultCodeMsg.FAIL.getCode(), null);
	}

	/**
	 * 返回失败带数据和消息
	 * @param data	失败数据
	 * @param msg	失败消息
	 * @param <T>	构建类型
	 * @return	返回封装数据
	 */
	public static <T> R<T> failed(T data, String msg) {
		log.error(msg);
		return restResult(data, ResultCodeMsg.FAIL.getCode(), msg);
	}

	/**
	 * 构建返回数据
	 * @param data	返回数据
	 * @param code	状态码
	 * @param msg	返回信息
	 * @param <T>	构建类型
	 * @return	返回构建数据
	 */
	private static <T> R<T> restResult(T data, int code, String msg) {
		R<T> apiResult = new R<>();
		apiResult.setCode(code);
		apiResult.setData(data);
		apiResult.setMsg(msg);
		return apiResult;
	}

}
